/**
 * @file   colorConfig.cpp
 * @author wolfhead <wolfhead@wolfhead-laptop>
 * @date   Mon Dec  5 20:55:11 2011
 * 
 * @brief  
 * 
 * 
 */
#include <iostream>
#include "colorConfig.h"
#include "colorRule.h"
#include <acapella/string/string_util.hpp>

ColorConfig::ColorConfig()
{
    RegisterColor("black", "1;30");
    RegisterColor("red", "1;31");
    RegisterColor("green", "1;32");
    RegisterColor("yellow", "1;33");
    RegisterColor("blue", "1;34");
    RegisterColor("white", "1;37");
    RegisterColor("default", "1;34");
}

ColorConfig::~ColorConfig()
{
    for (std::vector<ColorRule*>::iterator it = rules_.begin();
         it != rules_.end();
         ++it)
    {
        delete *it;
    }
}

int ColorConfig::RegisterColor(
    const std::string& name, 
    const std::string& color)
{
    colors_[acapella::StringUtil::ToLower(name)] 
        = _GetColor(color);
    return 0;
}

std::string ColorConfig::GetColor(const std::string& color) const
{
    std::map<std::string, std::string>::const_iterator it =
        colors_.find(acapella::StringUtil::ToLower(color));
    if (it == colors_.end())
    {
        return _GetColor(color);
    }

    return it->second;
}


int ColorConfig::LoadConfig(const std::string& config)
{
    std::vector<std::string> rules = 
        acapella::StringUtil::Explode(config, "|\n");

    for (size_t i = 0; i != rules.size(); ++i)
    {
        std::string& strRule = rules[i];
        strRule = acapella::StringUtil::Trim(strRule, " \t\n");
        if (strRule.empty())
        {
            continue;
        }

        std::vector<std::string> rule = 
            acapella::StringUtil::Explode(strRule, " \t");

        if (rule.size() != 3)
        {
            std::cerr << "rule format error : " << strRule << std::endl;
            return -1;
        }
        std::string type = acapella::StringUtil::Trim(rule[0], " \t");
        std::string param = acapella::StringUtil::Trim(rule[1], " \t");
        std::string color = acapella::StringUtil::Trim(rule[2], " \t");

        ColorRule* pRule = ColorRuleFactory::CreateColorRule(
            this,
            type,
            param,
            color);
        
        if (!pRule)
        {
            std::cerr << "create rule fail : " << strRule << std::endl;
            return -1;
        }

        rules_.push_back(pRule);
    }

    return 0;
}

std::string ColorConfig::ParseLine(const std::string& line)
{
    for (std::vector<ColorRule *>::iterator it = rules_.begin();
         it != rules_.end();
         ++it)
    {
        ColorRule * & pRule = *it;
        if (pRule->Match(line))
        {
            return (pRule->GetColor());
        }
    }

    return _GetColor("0");
}

const std::string& ColorConfig::GetDefaultColor() const
{
    static std::string defaultColor = _GetColor("0");
    return defaultColor;
}

std::string ColorConfig::_GetColor(const std::string& color) const
{
    return "\033[" + color + "m";
}
